package meter

import (
	"context"
	"fmt"
	"strconv"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/shopspring/decimal"
)

// EleOpenAccountRequest represents the request parameters for electrical meter account opening API
// EleOpenAccountRequest 表示电表开户API的请求参数
type EleOpenAccountRequest struct {
	Address   string `json:"address" v:"required"`   // 设备列表的address
	CID       string `json:"cid" v:"required"`       // 设备列表的cid
	AccountId string `json:"accountId" v:"required"` // 户号
	Money     string `json:"money" v:"required"`     // 金额
	Price     string `json:"price" v:"required"`     // 单价，数字字符串格式，例如：1块钱/kwh
}

// EleOpenAccountResponse represents the complete response from electrical meter account opening API
// EleOpenAccountResponse 表示电表开户API的完整响应
type EleOpenAccountResponse struct {
	Code           int    `json:"code"`           // 响应状态码
	Message        string `json:"message"`        // 响应消息
	AccountStatus  string `json:"accountStatus"`  // 账户状态
	OpenTime       string `json:"openTime"`       // 开户时间
	InitialBalance string `json:"initialBalance"` // 初始余额
	PricePerKwh    string `json:"pricePerKwh"`    // 每千瓦时价格
	Success        bool   `json:"success"`        // 操作是否成功
}

// Validate validates the EleOpenAccountRequest parameters using GoFrame validation
// Validate 使用GoFrame验证EleOpenAccountRequest参数
func (r *EleOpenAccountRequest) Validate() error {
	// First validate the struct fields using GoFrame
	if err := g.Validator().Data(r).Run(context.Background()); err != nil {
		return err
	}

	// Validate money format (must be numeric)
	if _, err := strconv.ParseFloat(r.Money, 64); err != nil {
		return fmt.Errorf("invalid money format: %s, must be a valid number", r.Money)
	}

	// Validate price format (must follow "X块钱/kwh" pattern)
	if _, err := strconv.ParseFloat(r.Price, 64); err != nil {
		return fmt.Errorf("invalid price format: %s, must be a valid number", r.Money)
	}

	return nil
}

// GetPriceValue extracts the numeric value from the price string
// GetPriceValue 从价格字符串中提取数值
func (r *EleOpenAccountRequest) GetPriceValue() (decimal.Decimal, error) {
	// Parse the numeric value
	return decimal.NewFromString(r.Price)
}
